home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / dopus412-gpl / program / arbiter.c < prev    next >
C/C++ Source or Header  |  2000-02-28  |  9KB  |  300 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "dopus.h"
  32. #include "view.h"
  33.  
  34. struct MsgPort *arbiter_reply_port;
  35. struct MsgPort *arbiter_msg_port=NULL;
  36. struct ProcessStart *arbiter_seglist=NULL;
  37. struct Message arbiter_startup;
  38.  
  39. install_arbiter()
  40. {
  41.     if (!(arbiter_reply_port=LCreatePort(NULL,0)) ||
  42.         !(arbiter_seglist=AllocMem(sizeof(struct ProcessStart),MEMF_CLEAR|MEMF_PUBLIC)))
  43.         return(0);
  44.  
  45.     arbiter_seglist->ps_NextSeg=NULL;
  46.     arbiter_seglist->ps_JMP=0x4ef9;
  47.     arbiter_seglist->ps_EntryPoint=(void *)arbiter_process;
  48.  
  49.     arbiter_startup.mn_Node.ln_Type=NT_MESSAGE;
  50.     arbiter_startup.mn_Node.ln_Pri=0;
  51.     arbiter_startup.mn_ReplyPort=arbiter_reply_port;
  52.     arbiter_startup.mn_Length=(UWORD)sizeof(struct ArbiterMessage);
  53.  
  54.     if (!(arbiter_msg_port=(struct MsgPort *)
  55.         CreateProc("dopus_arbiter",0,(long)arbiter_seglist>>2,4000))) return(0);
  56.  
  57.     PutMsg(arbiter_msg_port,&arbiter_startup);
  58.     return(1);
  59. }
  60.  
  61. void remove_arbiter()
  62. {
  63.     if (arbiter_msg_port) {
  64.         arbiter_command(ARBITER_REMOVE,NULL,0);
  65.         WaitPort(arbiter_reply_port);
  66.         GetMsg(arbiter_reply_port);
  67.     }
  68.  
  69.     if (arbiter_seglist) FreeMem(arbiter_seglist,sizeof(struct ProcessStart));
  70.     if (arbiter_reply_port) LDeletePort(arbiter_reply_port);
  71. }
  72.  
  73. arbiter_command(command,data,flags)
  74. int command;
  75. APTR data;
  76. int flags;
  77. {
  78.     struct ArbiterMessage arbiter_msg;
  79.     struct MsgPort command_port;
  80.  
  81.     CopyMem((char *)arbiter_reply_port,(char *)&command_port,sizeof(struct MsgPort));
  82.     NewList(&command_port.mp_MsgList);
  83.  
  84.     arbiter_msg.msg.mn_Node.ln_Type=NT_MESSAGE;
  85.     arbiter_msg.msg.mn_Node.ln_Pri=0;
  86.     arbiter_msg.msg.mn_ReplyPort=&command_port;
  87.     arbiter_msg.msg.mn_Length=(UWORD)sizeof(struct ArbiterMessage);
  88.     arbiter_msg.command=command;
  89.     arbiter_msg.data=data;
  90.     arbiter_msg.flags=flags;
  91.     PutMsg(arbiter_msg_port,(struct Message *)&arbiter_msg);
  92.     WaitPort(&command_port);
  93.     GetMsg(&command_port);
  94.  
  95.     return(arbiter_msg.command);
  96. }
  97.  
  98. struct LaunchList {
  99.     struct LaunchList *next;
  100.     struct ProcessStart *seglist;
  101.     struct ArbiterMessage launch_msg;
  102.     struct ArbiterMessage *reply_msg;
  103.     struct DOpusRemember *memory;
  104. };
  105.  
  106. void __saveds arbiter_process()
  107. {
  108.     struct Process *my_process;
  109.     struct Message *my_startup_message;
  110.     struct ArbiterMessage *arb_msg,*remove_msg=NULL;
  111.     struct LaunchList *first_launch=NULL,*launch,*launchpos;
  112.     struct MsgPort *message_reply;
  113.     char ret,remove=0;
  114.     int wait_mask;
  115.  
  116.     my_process=(struct Process *)FindTask(NULL);
  117.     my_process->pr_WindowPtr=(APTR)-1;
  118.     WaitPort(&my_process->pr_MsgPort);
  119.     my_startup_message=GetMsg(&my_process->pr_MsgPort);
  120.  
  121.     wait_mask=1<<my_process->pr_MsgPort.mp_SigBit;
  122.  
  123.     if (message_reply=LCreatePort(NULL,0))
  124.         wait_mask|=1<<message_reply->mp_SigBit;
  125.  
  126.     FOREVER {
  127.         if (message_reply) {
  128.             while (arb_msg=(struct ArbiterMessage *)GetMsg(message_reply)) {
  129.                 launch=first_launch;
  130.                 launchpos=NULL;
  131.                 while (launch) {
  132.                     if (arb_msg==&launch->launch_msg) {
  133.                         if (launchpos) launchpos->next=launch->next;
  134.                         else first_launch=launch->next;
  135.                         if (launch->reply_msg) {
  136.                             launch->reply_msg->command=arb_msg->command;
  137.                             ReplyMsg((struct Message *)launch->reply_msg);
  138.                         }
  139.                         LFreeRemember(&launch->memory);
  140.                         FreeMem(launch,sizeof(struct LaunchList));
  141.                         break;
  142.                     }
  143.                     launchpos=launch;
  144.                     launch=launch->next;
  145.                 }
  146.             }
  147.             if (remove_msg && !first_launch) {
  148.                 ReplyMsg((struct Message *)remove_msg);
  149.                 break;
  150.             }
  151.         }
  152.         while (arb_msg=(struct ArbiterMessage *)GetMsg(&my_process->pr_MsgPort)) {
  153.             ret=0;
  154.             switch (arb_msg->command) {
  155.                 case ARBITER_REMOVE:
  156.                     if (first_launch) {
  157.                         remove_msg=arb_msg;
  158.                         arb_msg=NULL;
  159.                     }
  160.                     else remove=1;
  161.                     break;
  162.                 case ARBITER_LAUNCH:
  163.                     if (message_reply &&
  164.                         (launch=AllocMem(sizeof(struct LaunchList),MEMF_CLEAR))) {
  165.                         struct ArbiterLaunch *arb_launch;
  166.                         struct MsgPort *port;
  167.  
  168.                         if ((launchpos=first_launch)) {
  169.                             while (launchpos->next) launchpos=launchpos->next;
  170.                         }
  171.                         if (launchpos) launchpos->next=launch;
  172.                         else first_launch=launch;
  173.  
  174.                         arb_launch=(struct ArbiterLaunch *)arb_msg->data;
  175.  
  176.                         launch->memory=arb_launch->launch_memory;
  177.  
  178.                         if (launch->seglist=LAllocRemember(&launch->memory,
  179.                             sizeof(struct ProcessStart),MEMF_PUBLIC|MEMF_CLEAR)) {
  180.  
  181.                             launch->seglist->ps_JMP=0x4ef9;
  182.                             launch->seglist->ps_EntryPoint=arb_launch->launch_code;
  183.  
  184.                             launch->launch_msg.msg.mn_Node.ln_Type=NT_MESSAGE;
  185.                             launch->launch_msg.msg.mn_ReplyPort=message_reply;
  186.                             launch->launch_msg.msg.mn_Length=sizeof(struct ArbiterMessage);
  187.                         
  188.                             launch->launch_msg.command=arb_msg->command;
  189.                             launch->launch_msg.data=arb_launch->data;
  190.                             launch->launch_msg.flags=arb_msg->flags;
  191.  
  192.                             if ((port=(struct MsgPort *)
  193.                                 CreateProc(arb_launch->launch_name,0,(long)launch->seglist>>2,4000))) {
  194.                                 PutMsg(port,(struct Message *)&launch->launch_msg);
  195.                                 if (arb_msg->flags&ARB_WAIT) {
  196.                                     launch->reply_msg=arb_msg;
  197.                                     arb_msg=NULL;
  198.                                 }
  199.                                 else ret=1;
  200.                             }
  201.                         }
  202.                         else {
  203.                             LFreeRemember(&launch->memory);
  204.                             FreeMem(launch,sizeof(struct ProcessStart));
  205.                         }
  206.                     }
  207.                     break;
  208.             }
  209.             if (arb_msg) {
  210.                 arb_msg->command=ret;
  211.                 ReplyMsg((struct Message *)arb_msg);
  212.             }
  213.         }
  214.         if (remove) break;
  215.         Wait(wait_mask);
  216.     }
  217.  
  218.     if (message_reply) LDeletePort(message_reply);
  219.     Forbid();
  220.     ReplyMsg(my_startup_message);
  221.     return;
  222. }
  223.  
  224. struct Screen *open_subprocess_screen(title,font,memkey,pens)
  225. char *title;
  226. struct TextFont *font;
  227. struct DOpusRemember **memkey;
  228. short *pens;
  229. {
  230.     struct ExtNewScreen newscreen;
  231.     struct TagItem *screentags;
  232.     struct TextAttr *screenattr;
  233.     struct Screen *screen;
  234.     UWORD *screen_drawinfo;
  235.  
  236.     if (!(screenattr=LAllocRemember(memkey,sizeof(struct TextAttr),MEMF_CLEAR)) ||
  237.         !(screentags=LAllocRemember(memkey,sizeof(struct TagItem)*5,MEMF_CLEAR)) ||
  238.         !(screen_drawinfo=LAllocRemember(memkey,sizeof(scr_drawinfo),0)))
  239.         return(NULL);
  240.  
  241.     CopyMem((char *)scr_drawinfo,(char *)screen_drawinfo,sizeof(scr_drawinfo));
  242.  
  243.     if (pens) {
  244.         screen_drawinfo[DETAILPEN]=pens[ARB_PEN_DETAIL];
  245.         screen_drawinfo[BLOCKPEN]=pens[ARB_PEN_BLOCK];
  246.     }
  247.  
  248.     screentags[0].ti_Tag=SA_DisplayID;
  249.     screentags[0].ti_Data=clone_screen(MainScreen,&newscreen);
  250.     screentags[1].ti_Tag=SA_Pens;
  251.     screentags[1].ti_Data=(ULONG)screen_drawinfo;
  252.     screentags[2].ti_Tag=SA_AutoScroll;
  253.     screentags[2].ti_Data=TRUE;
  254.     screentags[3].ti_Tag=SA_Interleaved;
  255.     screentags[3].ti_Data=TRUE;
  256.     screentags[4].ti_Tag=TAG_END;
  257.     screentags[4].ti_Data=0;
  258.  
  259.     if (system_version2) {
  260.         struct DimensionInfo dimbuf;
  261.         int width,height;
  262.  
  263.         if ((GetDisplayInfoData(NULL,
  264.             (char *)&dimbuf,
  265.             sizeof(struct DimensionInfo),
  266.             DTAG_DIMS,
  267.             screentags[0].ti_Data))) {
  268.  
  269.             width=(dimbuf.TxtOScan.MaxX-dimbuf.TxtOScan.MinX)+1;
  270.             height=(dimbuf.TxtOScan.MaxY-dimbuf.TxtOScan.MinY)+1;
  271.             if (newscreen.Width>width) newscreen.Width=width;
  272.             if (newscreen.Height>height) newscreen.Height=height;
  273.         }
  274.     }
  275.  
  276.     screenattr->ta_Name=font->tf_Message.mn_Node.ln_Name;
  277.     screenattr->ta_YSize=font->tf_YSize;
  278.  
  279.     newscreen.LeftEdge=0;
  280.     newscreen.TopEdge=0;
  281.     if (pens) {
  282.         newscreen.DetailPen=pens[ARB_PEN_DETAIL];
  283.         newscreen.BlockPen=pens[ARB_PEN_BLOCK];
  284.     }
  285.     else {
  286.         newscreen.DetailPen=0;
  287.         newscreen.BlockPen=1;
  288.     }
  289.     newscreen.Type=CUSTOMSCREEN|NS_EXTENDED;
  290.     newscreen.Font=screenattr;
  291.     newscreen.DefaultTitle=title;
  292.     newscreen.Gadgets=NULL;
  293.     newscreen.Extension=screentags;
  294.     newscreen.Depth=config->scrdepth;
  295.  
  296.     if (!(screen=OpenScreen((struct NewScreen *)&newscreen))) return(NULL);
  297.     load_palette(screen,config->new_palette);
  298.     return(screen);
  299. }
  300.